<?php

namespace App\Models;

use App\Models\ComModel;

/**
 * 单页模型
 */
class PagesModel extends ComModel
{

    public $tablename;
    private $categorys;

    public function __construct(...$param)
    {
        parent::__construct();
        $this->tablename = 'pages';
    }

    //新增和编辑全部数据时验证
    private function _validate($data, $id = 0)
    {
        if (!$data) {
            return ams_rt(1, '参数错误');
        }

        $data = esc($data);

        if (!$data['name']) {
            return ams_rt(1, '单页名称必须填写');
        }

        return ams_rt(0, 'ok', $data);
    }
    
    // 分页
    public function limit_page($page = 0, $size = 10, $total = 0, $param = [])
    {

        $page = max(1, (int) $page);
        $total = (int) $total;

        unset($param['page']);
        if ($param) {
            $param = esc($param);
        }

        if ($size > 0 && !$total) {
            $select = $this->db->table($this->tablename)->select('count(*) as total');
            $param = $this->_limit_page_where($select, $param);
            $query = $select->get();
            if (!$query) {
                log_message('error', '数据查询失败：' . $this->tablename);
                return [[], $total, $param];
            }
            $data = $query->getRowArray();
            $total = (int) $data['total'];
            $param['total'] = $total;
            unset($select);
            if (!$total) {
                return [[], $total, $param];
            }
        }

        $select = $this->db->table($this->tablename);
        $order = 'id desc';
        $param = $this->_limit_page_where($select, $param);
        $size > 0 && $select->limit($size, $size * ($page - 1));
        $query = $select->orderBy($order)->get();
        if (!$query) {
            log_message('error', '数据查询失败：' . $this->tablename);
            return [[], $total, $param];
        }
        $data = $query->getResultArray();
        $param['order'] = $order;
        $param['total'] = $total;

        return [$data, $total, $param];

    }

    /**
     * 条件查询
     *
     * @param    object    $select    查询对象
     * @param    intval    $where    是否搜索
     * @return    intval
     */
    protected function _limit_page_where(&$select, $param)
    {

        // 条件搜索
        if ($param) {

            // 关键字 + 自定义字段搜索
            if (isset($param['keyword']) && $param['keyword'] != '') {

                if ($param['id']) {
                    $select->where('id', (int) $$param['id']);
                } elseif ($param['ids']) {
                    $select->whereIn('id', $param['ids']);
                }

                if (isset($param['catname']) && $param['catname']) {
                    $select->where('catid IN (select id from `' . $this->dbprefix('news_category') . '` where `name` like "%' . $param['catname'] . '%")');
                }

                if (isset($param['title'])) {
                    $select->like('title', urldecode($param['title']));
                }
            }
            // 时间搜索
            if (isset($param['sdate']) && $param['sdate']) {
                $select->where('addtime BETWEEN ' . max((int) strtotime($param['sdate'] . ' 00:00:00'), 1) . ' AND ' . ($param['edate'] ? (int) strtotime($param['edate'] . ' 23:59:59') : SITE_TIME));
            } elseif (isset($param['edate']) && $param['edate']) {
                $select->where('addtime BETWEEN 1 AND ' . (int) strtotime($param['edate'] . ' 23:59:59'));
            }
            // 栏目查询
            // if (isset($param['catid']) && $param['catid']) {
            //     $cat['child'] ? $select->whereIn('catid', explode(',', $cat['childids'])) : $select->where('catid', (int)$param['catid']);
            // }
        }
        return $param;
    }

    public function setdisplayorder($id, $displayorder)
    {
        return $this->displayorder($this->tablename, $id, $displayorder);
    }

    public function get($id)
    {
        if (!$id) {
            return ams_rt(1, '参数错误');
        }
        $row = $this->db->table($this->tablename)->where('id', $id)->get()->getRowArray();
        if (!$row) {
            return ams_rt(1, '数据不存在', []);
        }
        if ($row['thumb']) {
            $row['thumb_info'] = $this->db->table('attachment')->select('filename,id,attachment')->where('id', intval($row['thumb']))->get()->getRowArray();
        }
        if (isset($row['attachment']) && $row['attachment']) {
            $attachment = explode(',', $row['attachment']);
            if (is_array($attachment)) {
                $row['attachment_info'] = $this->db->table('attachment')->select('filename,id,attachment')->whereIn('id', $attachment)->get()->getResultArray();
            }
        }
        return ams_rt(0, 'ok', $row);
    }

    public function del($id)
    {
        if (!$id) {
            return ams_rt(1, '参数错误');
        }
        $row = $this->db->table($this->tablename)->where('id', $id)->get()->getRowArray();
        if (!$row) {
            return ams_rt(1, '数据不存在');
        }
        $flag = $this->db->table($this->tablename)->where('id', $id)->delete();
        if ($flag && $row['child'] && $row['childids']) {
            $arr = explode(',', $row['childids']);
            $this->db->table($this->tablename)->whereIn('id', $arr)->delete();
            $this->db->table($this->tablename . '_data')->whereIn('id', $arr)->delete();
        }
        if ($flag) {
            return ams_rt(0, 'ok');
        }
        return ams_rt(1, '操作失败');
    }

    public function get_select()
    {
        $data = $_data = [];
        $data = $this->db->table($this->tablename)->orderBy('displayorder', 'asc')->orderBy('id', 'asc')->get()->getResultArray();
        $tree = new \App\Libraries\Tree();
        $data = $tree->get($data);
        if ($data) {
            foreach ($data as $k => $v) {
                $_data[$v['id']] = $v;
            }
        }
        return $_data;
    }

    public function add($data = [])
    {

        $rt = $this->_validate($data);
        if ($rt['code']) {
            return $rt;
        }
        $data = $rt['data'];

        if (!$data || !$data['name']) {
            return ams_rt(1, '分类名称必须填写');
        } elseif (!$data['enname']) {
            return ams_rt(1, '英文名称必须填写');
        } elseif (!ctype_alnum($data['enname'])) {
            $enname = str_replace([' ', '-', '_'], '', $data['enname']);
            if (!ctype_alnum($enname)) {
                return ams_rt(1, '英文名称不规范');
            }
        } elseif ($this->field_exitsts($this->tablename, 'name', $data['name'])) {
            return ams_rt(1, '分类已经存在了');
        } elseif ($this->field_exitsts($this->tablename, 'enname', $data['enname'])) {
            return ams_rt(1, '分类英文名称已经存在了');
        }

        $insert = [
            'pid' => isset($data['pid']) ? (int) $data['pid'] : 0,
            'pids' => '',
            'name' => trim($data['name']),
            'enname' => str_replace(['/', '-', '_'], '', trim($data['enname'])),
            'dirname' => str_replace(['/', '-', '_'], '', trim($data['enname'])),
            'child' => 0,
            'childids' => '',
            'show' => isset($data['show']) ? (int) $data['show'] : 0,
            'displayorder' => 0,
            'thumb' => isset($data['thumb']) ? intval($data['thumb']) : 0,
            'keywords' => $data['keywords'] ? ams_meta_keyword($data['keywords']) : '',
            'description' => isset($data['description']) ? $data['description'] : '',
            'content' => isset($data['content']) ? $data['content'] : '',
            'template'=>isset($data['template']) ? $data['template'] : '',
            'status' => isset($data['status']) ? (int) $data['status'] : 1,
            'inputtime' => time(),
            'updatetime' => time(),
        ];
        $this->db->table($this->tablename)->insert($insert);
        $id = $this->db->insertID();

        if ($id) {
            //附件归属
            if (isset($data['thumb']) && $data['thumb']) {
                $related = $this->tablename . '_cat-' . $id;
                $this->db->table('attachment')->where('id', intval($data['thumb']))->update(['related' => $related]);
            }
        }

        $this->repair();
        return ams_rt(0, '操作成功', $id);
    }

    public function edit($id = 0, $data = [])
    {

        $rt = $this->_validate($data);
        if ($rt['code']) {
            return $rt;
        }
        $data = $rt['data'];
        
        if (!$data || !$data['name']) {
            return ams_rt(1, '分类名称必须填写');
        } elseif (!$id) {
            return ams_rt(1, '参数不全');
        } elseif (!$data['enname']) {
            return ams_rt(1, '英文名称必须填写');
        } elseif (!ctype_alnum($data['enname'])) {
            $enname = str_replace([' ', '-', '_'], '', $data['enname']);
            if (!ctype_alnum($enname)) {
                return ams_rt(1, '英文名称不规范');
            }
        } elseif ($this->field_exitsts($this->tablename, 'name', $data['name'], $id)) {
            return ams_rt(1, '分类已经存在了');
        } elseif ($this->field_exitsts($this->tablename, 'enname', $data['enname'], $id)) {
            return ams_rt(1, '分类英文名称已经存在了');
        }

        $update = [
            'pid' => isset($data['pid']) ? (int) $data['pid'] : 0,
            'name' => $data['name'],
            'title' => (isset($data['title']) && $data['title']) ? $data['title'] : '',
            'enname' => str_replace(['/', '-', '_'], '', trim($data['enname'])),
            'dirname' => str_replace(['/', '-', '_'], '', trim($data['enname'])),
            'show' => isset($data['show']) ? (int) $data['show'] : 0,
            'thumb' => isset($data['thumb']) ? intval($data['thumb']) : 0,
            'keywords' => $data['keywords'] ? ams_meta_keyword($data['keywords']) : '',
            'description' => isset($data['description']) ? $data['description'] : '',
            'template'=>isset($data['template']) ? $data['template'] : '',
            'content' => isset($data['content']) ? $data['content'] : '',
            'updatetime' => time(),
        ];

        $this->db->table($this->tablename)->where('id', (int) $id)->update($update);

        //附件归属
        if (isset($data['thumb']) && $data['thumb']) {
            $related = $this->tablename . '_cat-' . $id;
            $this->db->table('attachment')->where('id', intval($data['thumb']))->update(['related' => $related]);
        }

        $this->repair();
        return ams_rt(0, '操作成功', $id);
    }

    private function get_categorys($data = [])
    {
        if (is_array($data) && !empty($data)) {
            foreach ($data as $catid => $c) {
                $this->categorys[$catid] = $c;
                $result = [];
                foreach ($this->categorys as $_k => $_v) {
                    $_v['pid'] && $result[] = $_v;
                }
            }
        }
        return true;
    }

    public function page_get_select()
    {
        $data = $_data = $cache = [];
        $data = $this->db->table($this->tablename)->orderBy('displayorder', 'asc')->orderBy('id', 'asc')->get()->getResultArray();
        if ($data) {
            $tree = new \App\Libraries\Tree();
            foreach ($data as $k => $v) {
                $cache[$v['id']] = $v;
            }
            $_data = $tree->get($cache);
        }
        return $_data;
    }

    private function get_pids($catid, $pids = '', $n = 1)
    {
        if ($n > 6 || !is_array($this->categorys) || !isset($this->categorys[$catid])) {
            return false;
        }
        $pid = $this->categorys[$catid]['pid'];
        $pids = $pids ? $pid . ',' . $pids : $pid;
        if ($pid) {
            $pids = $this->get_pids($pid, $pids, ++$n);
        } else {
            $this->categorys[$catid]['pids'] = $pids;
        }
        return $pids;
    }

    private function getChildids($catid, $n = 1)
    {
        $childids = $catid;
        if ($n > 6 || !is_array($this->categorys) || !isset($this->categorys[$catid])) {
            return $childids;
        }
        if (is_array($this->categorys)) {
            foreach ($this->categorys as $id => $cat) {
                if ($cat['pid'] && $id != $catid && $cat['pid'] == $catid) {
                    $childids .= ',' . $this->getChildids($id, ++$n);
                }
            }
        }
        return $childids;
    }

    public function getPdirname($catid)
    {
        if ($this->categorys[$catid]['pid'] == 0) {
            return '';
        }
        $t = $this->categorys[$catid];
        $pids = $t['pids'];
        $pids = explode(',', $pids);
        $catdirs = [];
        krsort($pids);
        foreach ($pids as $id) {
            if ($id == 0) {
                continue;
            }
            $catdirs[] = $this->categorys[$id]['dirname'];
            if ($this->categorys[$id]['pdirname'] == '') {
                break;
            }
        }
        krsort($catdirs);
        return implode('/', $catdirs) . '/';
    }

    public function getData()
    {
        $data = [];
        $_data = $this->db->table($this->tablename)->orderBy('displayorder ASC,id ASC')->get()->getResultArray();
        if (!$_data) {
            return $data;
        }
        foreach ($_data as $t) {
            $data[$t['id']] = $t;
        }
        return $data;
    }

    public function repair()
    {
        $this->categorys = $categorys = [];
        $this->categorys = $categorys = $this->getData();
        $this->get_categorys($categorys);

        if (is_array($this->categorys)) {
            foreach ($this->categorys as $catid => $cat) {
                $pids = $this->get_pids($catid);
                $childids = $this->getChildids($catid);
                $child = is_numeric($childids) ? 0 : 1;
                $this->categorys[$catid]['pids'] = $pids;
                $this->categorys[$catid]['child'] = $child;
                $this->categorys[$catid]['childids'] = $childids;

                if ($categorys[$catid]['pids'] != $pids
                    || $categorys[$catid]['childids'] != $childids
                    || $categorys[$catid]['child'] != $child) {
                    $this->db->table($this->tablename)->where('id', $catid)->update([
                        'pids' => $pids,
                        'child' => $child,
                        'childids' => $childids,
                    ]);
                }
            }
        }
    }

    public function cacheData()
    {
        $cache = [];
        $category = $this->db->table($this->tablename)->orderBy('displayorder ASC, id ASC')->get()->getResultArray();
        if ($category) {
            $CAT = $CAT_DIR = $level = [];
            foreach ($category as $c) {
                $pid = explode(',', $c['pids']);
                $level[] = substr_count($c['pids'], ',');
                $c['topid'] = isset($pid[1]) ? $pid[1] : $c['id'];
                $c['catids'] = explode(',', $c['childids']);
                $CAT[$c['id']] = $c;
                $CAT_DIR[$c['dirname']] = $c['id'];
            }
            $cache['category'] = $CAT;
            $cache['category_dir'] = $CAT_DIR;
        } else {
            $cache['category'] = [];
            $cache['category_dir'] = [];
        }
        $this->dcache->set('category', $cache['category']);
        $this->dcache->set('category-dir', $cache['category_dir']);
    }

}
